# utils.py
import ctypes

# 缓存屏幕尺寸
_screen_width = None
_screen_height = None


def get_screen_size():
    """
    使用 win32 API 获取屏幕尺寸（只调用一次，带缓存）
    """
    global _screen_width, _screen_height

    # 如果已经缓存了，直接返回
    if _screen_width is not None and _screen_height is not None:
        return _screen_width, _screen_height

    try:
        # 使用 Windows API 获取屏幕尺寸
        user32 = ctypes.windll.user32
        _screen_width = user32.GetSystemMetrics(0)  # SM_CXSCREEN - 屏幕宽度
        _screen_height = user32.GetSystemMetrics(1)  # SM_CYSCREEN - 屏幕高度
    except:
        # 如果 win32 API 失败，使用默认值
        _screen_width = 1920
        _screen_height = 1080

    return _screen_width, _screen_height


def create_centered_window(title="窗口", width=600, height=400, window_type='main', parent=None):
    """
    创建居中窗口（无闪烁，使用 win32 API 获取屏幕尺寸）

    Args:
        title: 窗口标题
        width: 窗口宽度
        height: 窗口高度
        window_type: 窗口类型 ('main' for Tk, 'top' for Toplevel)
        parent: 父窗口（仅对 Toplevel 有效）
    """
    # 获取屏幕尺寸
    screen_width, screen_height = get_screen_size()

    # 计算居中位置
    x = (screen_width - width) // 2
    y = (screen_height - height) // 2

    # 导入 tkinter（延迟导入，避免不必要的导入）
    import tkinter as tk

    # 创建窗口
    if window_type == 'main':
        window = tk.Tk()
    else:
        # 创建 Toplevel 窗口，如果有父窗口则传递父窗口参数
        if parent:
            window = tk.Toplevel(parent)
        else:
            window = tk.Toplevel()

    # 设置窗口属性
    window.title(title)
    window.geometry(f'{width}x{height}+{x}+{y}')

    return window


def bind_mousewheel(widget, event_widget=None):
    """
    为组件绑定鼠标滚轮事件，使其支持滚动功能
    兼容Canvas和Text组件

    Args:
        widget: 需要滚动的组件（Canvas或Text）
        event_widget: 需要绑定事件的组件，默认为widget本身

    Returns:
        function: 解绑函数，调用该函数可以解除绑定的事件
    """
    # 如果没有指定事件绑定组件，默认为widget本身
    if event_widget is None:
        event_widget = widget

    def _on_mousewheel(event):
        # 注意：Canvas和Text组件在初始时yview()会返回异常值
        # 但在滚动事件触发时（即用户实际操作时）UI已经完全初始化完成
        # 如果内容未完全显示
        if widget.yview() != (0.0, 1.0):
            # Tkinter的yview_scroll方法内部实现了边界检查
            # 当你已经滚动到顶部时，即使你继续向上滚动，yview_scroll方法也不会改变视图位置
            # 同样，当你滚动到底部时，继续向下滚动也不会改变视图位置
            widget.yview_scroll(int(-1 * (event.delta / 120)), "units")

        # 阻止默认内置默认行为，中止后续调用
        return "break"

    # 绑定鼠标滚轮事件，add="+"参数表示将这个绑定添加到现有的事件处理列表中，而不是替换它们
    binding_id = event_widget.bind("<MouseWheel>", _on_mousewheel, add="+")

    # 返回解绑函数
    def unbind_mousewheel():
        event_widget.unbind("<MouseWheel>", binding_id)

    return unbind_mousewheel